﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using ABB.Common.BusinessLogic.Contracts;
using ABB.Common.BusinessLogic.Helper;
using ABB.Common.DataModel;
using ABB.Common.BusinessLogic.Reporting;

namespace ABB.Common.BusinessLogic
{
    /// <summary>
    /// TableModule implementierung nach PoEAA.
    /// </summary>
    public class ReportModule : ModuleBase, IReportModule
    {
        private IChangeLogModule m_ChangeLogModule;

        public ReportModule(ProjectPlanningDataSet dataSet,
            IChangeLogModule changeLogModule)
            : base(dataSet)
        { this.m_ChangeLogModule = changeLogModule; }

        #region IReportModule Members

        /// <summary>
        /// Erstellt dynamisch eine DataTable mit sämtlichen Daten einer
        /// Report definition.
        /// </summary>
        /// <param name="report">Die Report definition, welche verwendet werden soll.</param>
        /// <param name="user">Der aktuelle Benutzer, wird benötigt um die Changes
        /// für den Benutzer zu finden und im Report zu markieren.</param>
        /// <returns>Eine dynamisch generiert <see cref="DataTable"/> mit sämtlichen
        /// im Report definierten Spalten und sämtlicher Daten aller Lots im DataSet.</returns>
        public DataTable BuildDataTableFromReportDefinition(ProjectPlanningDataSet.ReportRow report,
                    ProjectPlanningDataSet.UserRow user)
        {
            // Build data table schema
            ReportDataTableSchemaBuilder schemaBuilder = new ReportDataTableSchemaBuilder(
                                                            this.DataSet, report);
            ReportColumnMapping columnMapping;
            DataTable reportTable = schemaBuilder.BuildDataTable(out columnMapping);

            // Create DataLoader
            IReportDataLoader loader = new ReportDataLoader(this.DataSet, this.m_ChangeLogModule);

            // Fill data table
            ReportDataTableFiller tableFiller = new ReportDataTableFiller(report, columnMapping,
                                                        loader, user);
            tableFiller.FillTable(reportTable);

            return reportTable;
        }

        /// <summary>
        /// Gibt eine Liste von gefilterten und korrekt sortierten Lots aus dem DataSet zurück,
        /// wie von der übergebenen Report-Definition gefordert.
        /// </summary>
        /// <param name="report">Die Report definition, welche verwendet werden soll.</param>
        /// <param name="user">Der aktuelle Benutzer, wird benötigt um die Filter aufzulösen.</param>
        /// <returns><see cref="IEnumerable<ProjectPlanningDataSet.LotRow>"/>-Auflistung welche
        /// entsprechend gefiltert und sortiert ist.</returns>
        public IEnumerable<ProjectPlanningDataSet.LotRow> GetFilteredLotListFromReportDefinition(
                ProjectPlanningDataSet.ReportRow report, ProjectPlanningDataSet.UserRow user)
        {
            IReportDataLoader dataLoader = new ReportDataLoader(this.DataSet, this.m_ChangeLogModule);
            ReportFilterEvaluator filterEvaluator = new ReportFilterEvaluator(report, user, dataLoader);
            ReportSortEvaluator sortEvaluator = new ReportSortEvaluator(dataLoader, report, user);

            return sortEvaluator.GetSortedList(filterEvaluator.GetFilteredLots());
        }

        #endregion
    }
}
